<?php

namespace App\Services\User;


use App\Exceptions\ServiceException;
use App\Models\Auth\Menu;
use App\Models\User\Logininfor;
use App\Models\User\Role;
use App\Models\User\User;
use Faker\Provider\UserAgent;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Support\Facades\Log;
use Jenssegers\Agent\Agent;
use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth;
use \Exception;


class UserService
{
    private $title = '用户管理';
    /**
     * 处理登录业务逻辑
     * @param array $credentials 登录凭证（name + password）
     * @return array 包含用户信息和令牌
     * @throws AuthenticationException 认证失败时抛出异常
     */
    public function login(array $credentials)
    {
        // 从登录凭证中获取用户名和密码，增加参数校验，确保存在这两个字段
        if (!isset($credentials['user_name']) || !isset($credentials['password'])) {
            throw new ServiceException('缺少必要的登录参数（用户名或密码）', 400);
        }
        $userName = $credentials['user_name'];
        $password = $credentials['password'];
        // 直接查询数据库验证用户名
        $user = User::query()->with('dept')->where('user_name', $userName)->first();
        // 检查用户是否存在
        $errorMsg = '';
        if (!$user) {
            $errorMsg = '账号不存在';
        }
        // 检查密码是否正确
        if (!Hash::check($password, $user->password)) {
            $errorMsg = $errorMsg ?? '密码错误';
        }
        // 检查账号状态（0正常 1停用）
        if ($user->status == '1') {
            $errorMsg = $errorMsg ?? '该账号已被禁用，请联系管理员';
        }
        // 检查账号是否被删除（0代表存在 2代表删除）
        if ($user->del_flag == '2') {
            $errorMsg = $errorMsg ?? '该账号已被删除';
        }
        // 获取客户端 IP
        $loginIp =  getClientIp();
        // 获取当前时间
        $loginDate = date('Y-m-d H:i:s');
        $agent = new Agent();
        //添加登录日志
        $logMsg = [
            'user_name'         => $userName,
            'ipaddr'            => $loginIp,//登录ip
            'browser'           => $agent->platform(),//浏览器类型
            'os'                => $agent->browser(),//操作系统
            'status'            => empty($errorMsg) ? 0 : 1,//登录状态
            'msg'               => $errorMsg ?? '登录成功',//提示消息
            'login_time'        => $loginDate,//访问时间
        ];
        Logininfor::query()->insert($logMsg);
        if($errorMsg){
            throw new Exception($errorMsg, 400);
        }
        // 更新用户的登录 IP 和登录时间
        User::where('user_id', $user->user_id)->update(['login_ip'=>$loginIp,'login_date'=>$loginDate]);
        // 生成新的访问令牌
        $token = auth('api')->attempt(['user_name' => $credentials['user_name'], 'password' => $credentials['password']]) ?: '';
        // 返回用户信息和令牌，补充更多用户信息，与数据库字段对应
        return [
            'token' => 'Bearer '.$token,
        ];
    }

    /**
     * @Notes:获取用户信息
     * @author: Liao Hong
     * @Time: 2025/10/21   14:38
     * @Interface getInfo
     */
    public function getInfo()
    {
        $user = User::query()->with(['roles'=>function($query){
            $query->with(['permissions:perms']);
        },'dept'])->find(user_id())->toArray();
        $permissions = $roles =  [];
        if(!empty($user['roles'])){
            foreach ($user['roles'] as $v1){
                if(!empty($v1['role_key'])){
                    array_push($roles,$v1['role_key']);
                }
                if(!empty($v1['permissions'])){
                    foreach ($v1['permissions'] as $v2){
                        if (!empty($v2['perms'])){
                            $permissions[] = $v2['perms'];

                        }
                    }
                }
            }
        }
        $data = [
            'isDefaultModifyPwd'=>false,
            'isPasswordExpired'=>false,
            'permissions'=>is_super() ? ["*:*:*"] : $permissions,
            'roles'=>array_unique($roles),
            'user'=>$user,
        ];
        return $data;
    }

    /**
     * @Notes:获取路由地址
     * @author: Liao Hong
     * @Time: 2025/10/21   15:55
     * @Interface getRouters
     */
    public function getRouters()
    {
        $user = User::query()->with(['roles'=>function($query){
            $query->with(['permissions:menu_id']);
        }])->find(user_id())->toArray();
        $menuIds = [];
        $isSuper = is_super();
        if($isSuper){
            //如果是超管
            $rows = Menu::query()->where('parent_id',0)->get();
        }else{
            if(!empty($user['roles'])){
                foreach ($user['roles'] as $v1){
                    if(!empty($v1['permissions'])){
                        foreach ($v1['permissions'] as $v2){
                            if (!empty($v2['menu_id'])){
                                array_push($menuIds,$v2['menu_id']);
                            }
                        }
                    }
                }
            }
            $menuIds = array_unique($menuIds);
            $rows = Menu::query()->where('parent_id',0)->whereIn('menu_id',$menuIds)->get();
        }
        $data = [];
        foreach ($rows as $i1=>$v1){
            $data[$i1]=[
                'alwaysShow'    => true,
                'component'     => $v1->component ?? 'Layout',
                'hidden'        => false,
                'name'          => $v1->path,
                'path'          => '/'.$v1->path,
                'redirect'      => 'noRedirect',
                'meta'          =>[
                    'icon' =>$v1->icon,
                    'link' =>'',
                    'noCache' =>$v1->is_cache == 1 ? false : true,
                    'title' =>$v1->menu_name,
                ]
            ];
            if($isSuper){
                $children = Menu::query()->where('parent_id',$v1->menu_id)->get();
            }else{
                $children = Menu::query()->where('parent_id',$v1->menu_id)->whereIn('menu_id',$menuIds)->get();
            }
            if(!empty($children)){
                foreach ($children as $m =>$item){
                    $component = $item->component;
                    if(empty($item->component)){
                        $isMenu = Menu::query()
                            ->where([
                                ['parent_id','=',$item->menu_id],
                                ['component','<>',''],
                                ['path','<>',''],
                            ])
                            ->exists();
                        $component = !empty($isMenu) ? 'ParentView' : '';
                    }
                    $data[$i1]['children'][$m] = [
                        'component' => $component,
                        'hidden'    => false,
                        'name'      => $item->path,
                        'path'      => $item->path,
                        'meta'      => [
                            'icon' =>$item->icon,
                            'link' =>'',
                            'noCache' =>$item->is_cache == 1 ? false : true,
                            'title' =>$item->menu_name,
                        ],
                    ];
                    $children_v1 = Menu::query()
                        ->where([
                            ['parent_id','=',$item->menu_id],
                            ['component','<>',''],
                            ['path','<>',''],
                        ])
                        ->get();
                    if(!empty($children_v1)){
                        foreach ($children_v1 as $n=>$v2){
                            $component = $v2->component;
                            $data[$i1]['children'][$m]['children'][] = [
                                'component' => $component,
                                'hidden'    => false,
                                'name'      => $v2->path,
                                'path'      => $v2->path,
                                'meta'      => [
                                    'icon' =>$v2->icon,
                                    'link' =>'',
                                    'noCache' =>$v2->is_cache == 1 ? false : true,
                                    'title' =>$v2->menu_name,
                                ],
                            ];
                        }
                    }
                }
            }
        }
        return $data;
    }
    /**
     * @Notes:获取单条数据
     * @param $params
     * @author: Liao Hong
     * @Time: 2025/10/21   14:01
     * @Interface getRow
     */
    public function getRow($params)
    {
        if(isset($params['user_id'])){
            $user = User::query()->with(['dept','roles'])->find($params['user_id'])->toArray();
            $roles = $user['roles'];
            $roleIds = array_column($roles,'role_id');
            $result = [
                'data'      => $user,
                'roleIds'   => $roleIds,
                'roles'     => $roles,
            ];
        }else{
            $roles = Role::query()->get()->toArray();
            $result = [
                'roles'     => $roles,
            ];
        }
        return $result;
    }
    /**
     * @Notes:添加用户
     * @author: Liao Hong
     * @Time: 2025/10/20   13:30
     * @Interface add
     */
    public function add($params = []){
       $params['created_at'] = getTime();
       $params['create_by']  = user()->user_name;
       Db::beginTransaction();
       try {
            //角色id
            $roleIds = [];
            if(isset($params['role_ids']) && !empty($params['role_ids'])){
                $roleIds = $params['role_ids'];
                unset($params['role_ids']);
            }
            $userId = User::query()->insertGetId($params);
            if(!empty($roleIds)){
                $userRole = [];
                foreach ($roleIds as $item){
                    $userRole[] = [
                        'user_id' =>$userId,
                        'role_id' =>$item,
                    ];
                }
                DB::table('user_role')->insert($userRole);
            }
            DB::commit();
           addLog($this->title,'1',true);
            return true;
        }catch (Exception $exception){
           addLog($this->title,'1',false);
            DB::rollBack();
           throw new ServiceException($exception->getMessage(), 201);
        }
    }
    /**
     * @Notes:修改用户
     * @author: Liao Hong
     * @Time: 2025/10/20   13:30
     * @Interface add
     */
    public function update($params = []){
        $params['updated_at']      = getTime();
        $params['pwd_update_date'] = getTime();
        $params['update_by'] = user()->user_name;
        if(isset($params['password']) && !empty($params['password'])){
            $params['password'] = Hash::make($params['password']);
        }
        //角色id
        Db::beginTransaction();
        try {
        $roleIds = [];
        if(isset($params['role_ids']) && !empty($params['role_ids'])){
            $roleIds = $params['role_ids'];
            unset($params['role_ids']);
        }
        if(!empty($roleIds)){
            $userRole = [];
            foreach ($roleIds as $item){
                $userRole[] = [
                    'user_id' =>$params['user_id'],
                    'role_id' =>$item,
                ];
            }
            //删除旧关联
            DB::table('user_role')->where('user_id',$params['user_id'])->delete();
            //添加新关联
            DB::table('user_role')->insert($userRole);
        }
        User::query()->where('user_id',$params['user_id'])->update($params);
        DB::commit();
        addLog($this->title,'2',true);
        return true;
        }catch (\Exception $exception){
            addLog($this->title,'2',false);
            DB::rollBack();
            throw new ServiceException($exception->getMessage(), 201);
        }
    }
    /**
     * @Notes:删除用户
     * @author: Liao Hong
     * @Time: 2025/10/20   13:30
     * @Interface add
     */
    public function delete($params = []){
        //删除用户角色关联
        DB::table('user_role')->where('user_id',$params['user_id'])->delete();
        //删除用户
        User::query()->where('user_id',$params['user_id'])->delete();
        addLog($this->title,'3',true);
        return true;
    }
    /**
     * @Notes:用户列表
     * @author: Liao Hong
     * @Time: 2025/10/20   13:30
     * @Interface add
     */
    public function list($parmas){
        $query = [];
        if(isset($parmas['user_name']) && !empty($parmas['user_name'])){
            $query[] = ['user_name','like','%'.$parmas['user_name'].'%'];
        }
        if(isset($parmas['phonenumber']) && !empty($parmas['phonenumber'])){
            $query[] = ['phonenumber','like','%'.$parmas['phonenumber'].'%'];
        }
        if(isset($parmas['dept_id']) && !empty($parmas['dept_id'])){
            $query[] = ['dept_id','=',$parmas['dept_id']];
        }
        if(isset($parmas['status']) && !empty($parmas['status'])){
            $query[] = ['status','=',$parmas['status']];
        }
        $limit = isset($parmas['limit']) ? $parmas['limit'] : 10;
        $row = User::query()->with(['dept','roles'])->where($query)->paginate($limit);
        $row = empty($row) ?  [] :$row->toArray();
        return $row;

    }

}
